package com.obelisco.vista.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import nextapp.echo2.app.ApplicationInstance;
//import nextapp.echo2.app.RuntimeExceptionCallback;

import nextapp.echo2.webcontainer.WebContainerServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.obelisco.vista.inicio.Aplicacion;

/**
 * EchoServer implementation.
 */
public class ObeliscoInicioServlet extends WebContainerServlet {
	
	private static final long   serialVersionUID = 1L;
    private String              m_name           = null;

    
	private ApplicationContext context;
	private String applicationName;

	protected ApplicationContext getApplicationContext() {
		return context;
	}

	private void initApplicationContextIfNeeded() {
		if (context == null) {
			context = WebApplicationContextUtils
					.getWebApplicationContext(getServletContext());
		}
	}

	private void retrieveApplicationNameIfNeeded() {
		if (applicationName == null) {
			String[] beanNames = context
					.getBeanNamesForType(ApplicationInstance.class);
			if (beanNames == null || beanNames.length == 0) {
				throw new IllegalArgumentException(
						"A bean of type "
								+ "nextapp.echo2.app.ApplicationInstance must be declared "
								+ "in the application context.");
			}
			if (beanNames.length > 1) {
				throw new IllegalArgumentException(
						"There must only be one "
								+ "bean of type nextapp.echo2.app.ApplicationInstance declared "
								+ "in the application context.");
			}
			this.applicationName = beanNames[0];
		}
	}

	public ApplicationInstance newApplicationInstance() {
		initApplicationContextIfNeeded();
		retrieveApplicationNameIfNeeded();
		ApplicationInstance app = (ApplicationInstance) context.getBean(applicationName);
		app.setContextProperty(Aplicacion.ID_SPRING_CONTEXT, context);
		return app;
	}	

	protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        // get the request path, but trim off the leading part that is mapped to
        // the webapp and servlet
        StringBuilder sb = new StringBuilder();
        sb.append("^");
        sb.append(request.getContextPath());
        sb.append(request.getServletPath());
        
        m_name = request.getRequestURI().replaceFirst(sb.toString(), "");
        
        //If the querry parameters are null, this means it is a new
        //request for the page, clear any existing ApplicationInstance
        //we may have. Otherwise, this is a client side syncronization, etc, which
        //has a parameter of serviceId=something
        //TODO: Checking for null is probably too simple. We should probably really
        //check that the query string does not contain serviceId=something. This allows
        //us to use or own query strings.
        if (request.getQueryString() == null)
        {
            //Get the session
            HttpSession session = request.getSession();
            session.removeAttribute("Echo2UserInstance:" + this.getServletName());
        }
		
		try {
			super.process(request, response);
		} catch (Throwable t) {
			t.printStackTrace(System.out);
			redirectToErrorServlet(request, response, t);
		}
		
        m_name = null;
	}
	
	protected void redirectToErrorServlet(HttpServletRequest request, HttpServletResponse response, Throwable t) throws IOException, ServletException {
		// stick the error in the Session so we can get it on the other page
		HttpSession session = request.getSession();
		session.setAttribute("obelisco.servletThrowable", t);

		String uri = request.getRequestURI();
		int lastSlash = uri.lastIndexOf("/");
		uri = uri.substring(0,lastSlash+1);
		uri += "obeliscoerrorpage";
		// 
		// Not sure which is a better way to redirect
		// from this "temporary" page. sendRedirect() works
		// however I have seen Internet comments that
		// question this.
		if (true) {
			response.sendRedirect(uri);
		} else {
			RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(uri);
			if (dispatcher == null) {
				throw new IOException("No Request Dispatcher for " + uri);
			}
			dispatcher.forward(request, response);
		}
	}
	

}
